package jwei.apps.indextank;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import jwei.apps.indextank.adapters.RestaurantsCursorAdapter;
import jwei.apps.indextank.client.IndexTankClient;
import jwei.apps.indextank.client.IndexTankClient.Index;
import jwei.apps.indextank.client.IndexTankClient.Query;
import jwei.apps.indextank.client.IndexTankClient.SearchResults;
import jwei.apps.indextank.db.RestaurantDb;
import jwei.apps.indextank.db.RestaurantCache.RestaurantsCache;
import jwei.apps.indextank.objects.Constants;
import jwei.apps.indextank.objects.Restaurant;
import jwei.apps.indextank.service.LocationProvider;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

public class SearchIndexActivity extends ListActivity {

    private ProgressDialog pd;

    private RestaurantsCursorAdapter rca;

    private String type;

    private Button search;

    private EditText searchText;

    private final String LOG_TAG = "SearchIndexActivity";

    private Location curLocation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.search_layout);

        Intent i = getIntent();
        type = i.getStringExtra("type");

        search = (Button) findViewById(R.id.search_button);
        searchText = (EditText) findViewById(R.id.search_bar);

        searchText.setHint("Search Index (" + type + "):");

        search.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                String term = searchText.getText().toString();
                if (curLocation != null) {
                    if (term.length() > 0) {
                        new SearchIndexTask().execute(type, term);
                    } else {
                        Toast t = Toast.makeText(SearchIndexActivity.this, "Please enter a search term.",
                                Toast.LENGTH_SHORT);
                        t.show();
                    }
                } else {
                    Toast t = Toast.makeText(SearchIndexActivity.this,
                            "Could not retrieve your current location - please make sure GPS is turned on!",
                            Toast.LENGTH_SHORT);
                    t.show();
                }
            }

        });

        // retrieve the user's current location
        LocationProvider lp = new LocationProvider(this);
        curLocation = lp.getLocationAndUpdate();
        if (curLocation != null) {
            System.out.println("USER AT: " + curLocation.getLatitude() + " " + curLocation.getLongitude());
        } else {
            Toast t = Toast
                    .makeText(SearchIndexActivity.this,
                            "Could not retrieve your current location - please make sure GPS is turned on!",
                            Toast.LENGTH_SHORT);
            t.show();
        }
    }

    private class SearchIndexTask extends AsyncTask<String, String, Integer> {

        @Override
        protected void onPreExecute() {
            pd = ProgressDialog.show(SearchIndexActivity.this, "Searching IndexTank",
                    "Please wait while we search through our database...", true, false);
        }

        protected Integer doInBackground(String... param) {
            IndexTankClient client = new IndexTankClient(Constants.INDEX_URL);
            Index index = client.getIndex(Constants.INDEX_NAME);

            String query = param[0] + ":" + param[1].trim();
            try {
                index.addFunction(5, "-miles(d[0], d[1], q[0], q[1])");

                // search by distance, and include all given fields
                SearchResults results = index.search(Query.forString(query).withLength(20)
                        .withFetchFields("name", "address", "city", "state", "postcode", "telephone", "website",
                                "tags", "dishes", "ingredients").withScoringFunction(5).withQueryVariable(0,
                                (float) curLocation.getLatitude()).withQueryVariable(1,
                                (float) curLocation.getLongitude()));

                if (results.matches < 1) { return 0; }
                Log.i(LOG_TAG, "Matches: " + results.matches);

                List<Restaurant> rs = new ArrayList<Restaurant>();
                for (Map<String, Object> document : results.results) {
                    String docid = (String) document.get("docid");
                    String name = (String) document.get("name");
                    if (docid.equals("") || name.equals("")) {
                        Log.e(LOG_TAG, "Error: DocId or Name was empty.");
                        continue;
                    } else {
                        Restaurant r = new Restaurant(docid, name);
                        r.setStreet((String) document.get("address"));
                        r.setCity((String) document.get("city"));
                        r.setState((String) document.get("state"));
                        r.setZip((String) document.get("postcode"));
                        r.setPhone((String) document.get("telephone"));
                        r.setUrl((String) document.get("website"));
                        r.setTags((String) document.get("tags"));
                        r.setDishes((String) document.get("dishes"));
                        r.setIngredients((String) document.get("ingredients"));
                        rs.add(r);
                    }
                }

                // here we should have all search results, ready to be cached
                RestaurantDb rdb = RestaurantDb.getInstance();
                rdb.refreshCache(getContentResolver());

                int rows = rdb.addProducts(getContentResolver(), rs);
                return rows;
            } catch (Exception e) {
                e.printStackTrace();
            }

            return -1;
        }

        protected void onProgressUpdate(String... progress) {
            pd.setMessage(progress[0]);
        }

        protected void onPostExecute(Integer results) {
            if (results > 0) {
                // query for products
                Cursor c = getContentResolver().query(RestaurantsCache.CONTENT_URI, null,
                        RestaurantsCache.IS_QUEUE + "=0", null, null);
                startManagingCursor(c);
                Log.i(LOG_TAG, "QUERIED " + c.getCount() + " RESTAURANTS FROM CACHE");
                String[] from = new String[] { RestaurantsCache.NAME, RestaurantsCache.STREET };
                int[] to = new int[] { R.id.restaurant_name, R.id.restaurant_street };

                // set list adapter
                rca = new RestaurantsCursorAdapter(SearchIndexActivity.this, R.layout.search_list_entry, c, from, to);
                setListAdapter(rca);
            } else {
                Toast t = Toast.makeText(SearchIndexActivity.this, "Sorry - did not retrieve any results!",
                        Toast.LENGTH_SHORT);
                t.show();
            }
            if (pd.isShowing()) {
                pd.dismiss();
            }
        }
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        if (rca == null) { return; }

        Cursor c = (Cursor) rca.getItem(position);

        Intent i = new Intent(SearchIndexActivity.this, RestaurantDetailsActivity.class);
        String docid = c.getString(c.getColumnIndex(RestaurantsCache.DOC_ID));
        i.putExtra("docid", docid);
        i.putExtra("name", c.getString(c.getColumnIndex(RestaurantsCache.NAME)));
        i.putExtra("street", c.getString(c.getColumnIndex(RestaurantsCache.STREET)));
        i.putExtra("city", c.getString(c.getColumnIndex(RestaurantsCache.CITY)));
        i.putExtra("state", c.getString(c.getColumnIndex(RestaurantsCache.STATE)));
        i.putExtra("zip", c.getString(c.getColumnIndex(RestaurantsCache.ZIP)));
        i.putExtra("url", c.getString(c.getColumnIndex(RestaurantsCache.WEBSITE)));
        i.putExtra("phone", c.getString(c.getColumnIndex(RestaurantsCache.PHONE)));
        i.putExtra("tags", c.getString(c.getColumnIndex(RestaurantsCache.TAGS)));
        i.putExtra("dishes", c.getString(c.getColumnIndex(RestaurantsCache.DISHES)));
        i.putExtra("ingredients", c.getString(c.getColumnIndex(RestaurantsCache.INGREDIENTS)));
        startActivity(i);
    }

}
